package com.hoapital.outpbillwork.billWorkHandler;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hoapital.outpbillwork.module.entity.*;
import com.hoapital.outpbillwork.module.mapper.*;
import com.hospital.api.RemoteBillService;
import com.hospital.common.core.constants.AllFinalValueUtils;
import com.hospital.common.core.exception.ExceptionHelp;
import com.hospital.common.core.exception.ExceptionHelpEnum;
import com.hospital.common.core.function.PushMessage;
import com.hospital.common.core.module.controller.dto.BillDto;
import com.hospital.common.core.module.controller.dto.ClinicItem;
import com.hospital.common.core.module.controller.dto.ClinicType;
import com.hoapital.outpbillwork.module.controller.vo.ApplyInfo;
import com.hospital.common.core.module.controller.vo.CancelOrder;
import com.hoapital.outpbillwork.module.controller.vo.OrderInfo;
import com.hospital.common.core.module.controller.vo.Receive;

import com.hospital.common.core.module.entity.WxPayEntity;
import com.hospital.common.core.result.SuccessTip;
import com.hospital.common.core.result.Tip;
import com.hospital.common.core.utils.DateUtil;
import com.hospital.common.core.utils.SpringContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import javax.servlet.http.HttpServletRequest;
import java.io.IOError;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author lvyao
 * @description 计费方法类
 * @date 2021/12/13
 */
@Slf4j
public class AbstractBillWorkBusiness extends AbstractBaseBusiness implements BillWorkHandler {
    @Autowired
    private InpBillDetailMapper inpBillDetailMapper = SpringContextHolder.getBean(InpBillDetailMapper.class);
    @Autowired
    private DrugPrescMasterMapper drugPrescMasterMapper = SpringContextHolder.getBean(DrugPrescMasterMapper.class);
    @Autowired
    private OutpBillItemsTempMapper outpBillItemsTempMapper = SpringContextHolder.getBean(OutpBillItemsTempMapper.class);
    @Autowired
    private OutpOrderDescTempMapper outpOrderDescTempMapper = SpringContextHolder.getBean(OutpOrderDescTempMapper.class);
    @Autowired
    private OutpDoctorAssistantMapper outpDoctorAssistantMapper = SpringContextHolder.getBean(OutpDoctorAssistantMapper.class);
    @Autowired
    private ClinicVsChargeMapper clinicVsChargeMapper = SpringContextHolder.getBean(ClinicVsChargeMapper.class);
    @Autowired
    private LabTestItemsMapper labTestItemsMapper = SpringContextHolder.getBean(LabTestItemsMapper.class);
    @Autowired
    private OutpOrderDescMapper outpOrderDescMapper = SpringContextHolder.getBean(OutpOrderDescMapper.class);
    @Autowired
    private OutpPrepayRcptTempMapper outpPrepayRcptTempMapper = SpringContextHolder.getBean(OutpPrepayRcptTempMapper.class);
    @Autowired
    private AppConfigerBaseinfoMapper appConfigerBaseinfoMapper = SpringContextHolder.getBean(AppConfigerBaseinfoMapper.class);
    @Autowired
    private OutpDoctorPrescItemsMapper outpDoctorPrescItemsMapper = SpringContextHolder.getBean(OutpDoctorPrescItemsMapper.class);
    @Autowired
    private LabTestMasterMapper labTestMasterMapper = SpringContextHolder.getBean(LabTestMasterMapper.class);
    @Autowired
    private ExamAppointsMapper examAppointsMapper = SpringContextHolder.getBean(ExamAppointsMapper.class);
    @Autowired
    private ExamItemsMapper examItemsMapper = SpringContextHolder.getBean(ExamItemsMapper.class);
    @Autowired
    private ExamMasterMapper examMasterMapper = SpringContextHolder.getBean(ExamMasterMapper.class);

    @Autowired
    private ExceptionHelp exceptionHelp;

    @Autowired
    private PushMessage pushMessage = SpringContextHolder.getBean(PushMessage.class);

    @Override
    public Tip billWork(Receive receive, HttpServletRequest request) throws ExceptionHelp {
        //检查入参以及基础数据是否异常
        exceptionHelp = checkAllbill(receive);
        if (exceptionHelp != null) {
            throw exceptionHelp;
        }
        //循环获取需要计费的患者的订单号
        List<WxPayEntity> wxPayEntityList = receive.getSettlePatientInfo();
        for (WxPayEntity wxPayEntity : wxPayEntityList) {
            //获取申请订单数据
            Map<String, Object> objectMap = getBillNo(receive.getSettleFlag(), wxPayEntity);
            OutpPrepayRcptTemp outpPrepayRcptTemp = (OutpPrepayRcptTemp) objectMap.get(AllFinalValueUtils.OUTP_PRE_RCPT_TEMP);
            List<OrderVsBillno> orderVsBillnoList = (List<OrderVsBillno>) objectMap.get(AllFinalValueUtils.ORDER_VS_BILL_LIST);
            String rcptNo = outpPrepayRcptTemp.getRcptNo();
            String billNos = orderVsBillnoList.stream().map(p -> p.getBillNo()).collect(Collectors.joining(","));
            //获取HIS业务单号数组
            String[] billNoList = billNos.split(",");
            //个人结算数据检查
            boolean checkSingleSettleData = checkSingleSettleData(wxPayEntity, billNoList);
            if (checkSingleSettleData) {
                //获取基本信息
                OutpOrderDescTemp outpOrderDescTemp = (OutpOrderDescTemp) getList(new QueryWrapper<OutpOrderDescTemp>(), billNoList[0], OutpOrderDescTemp.class).get(0);
                String chargeType = null;
                String patientId = outpOrderDescTemp == null ? wxPayEntity.getPatientId() : outpOrderDescTemp.getPatientId();
                String outpID = outpOrderDescTemp == null ? wxPayEntity.getOutpId() : String.valueOf(outpOrderDescTemp.getOutpId());
                //获取费别
                chargeType = outpID == null || outpID.trim().equals("") ? clinicVsChargeMapper.getPatChargeType(patientId) : clinicVsChargeMapper.getChargeType(patientId, outpID);
                if (chargeType == null || chargeType.isEmpty()) {
                    chargeType = AllFinalValueUtils.OWN_CHARGE_TYPE;
                }
                receive.getSettlePatientInfo().get(receive.getSettlePatientInfo().indexOf(wxPayEntity)).setBillNo(billNos);
                receive.getSettlePatientInfo().get(receive.getSettlePatientInfo().indexOf(wxPayEntity)).setRcptNo(rcptNo);
                List<ClinicType> clinicTypeList = new ArrayList<>();
                //获取计费的门诊单号并处理不同医嘱类别的特殊表数据
                for (String billNo : billNoList) {
                    clinicTypeList.addAll(commBill(receive, billNo));
                }
                try {
                    clinicTypeList.addAll(wxPayEntity.getClinicTypeList() == null ? null : wxPayEntity.getClinicTypeList());
                } catch (NullPointerException e) {
                }
                //获得计费接口入参
                BillDto billDto = getBillDto(chargeType, receive, clinicTypeList, patientId, outpID);
                try {
                    boolean sendBill = pushMessage.sendBillMsg(billDto, outpOrderDescTempMapper.getBillUrl());
                    if (!sendBill) {
                        throw new ExceptionHelp(ExceptionHelpEnum.FILED_REQ_BILL_SERVER);
                    }
                } catch (IOError e) {
                    throw new ExceptionHelp(ExceptionHelpEnum.SERVICE_ERR);
                }
            }
            //判断多HIS业务单计费时不做检验申请推送
            List<Boolean> collect = orderVsBillnoList.stream().map(p -> p.getOrderType() != null && p.getOrderType().equals("C")).collect(Collectors.toList());
            Boolean boo = new Boolean(false);
            boolean contains = collect.contains(boo);
            if (!contains) {
                //推送计费消息到检验、检查
                Map<String, String> hl7InterConfig = getHl7InterConfig(orderVsBillnoList.get(0).getOrderType());
                String filePath = hl7InterConfig.get("filePath");
                String postHl7Url = hl7InterConfig.get("postHl7Url");
                String xmlHl7Url = hl7InterConfig.get("xmlHl7Url");
//                if (update >= 0) {
                filePath += billNos + ".xml";
                pushMessage.sendLabApplyInfo(receive.getHospitalCode(), receive.getHospitalName(), xmlHl7Url, filePath, postHl7Url, "1");
//                pushMessage.sendLabBillInfo(AllFinalValueUtils.MESSAGE_EVENT_NAME_ALL_LAB, receive.getHospitalCode(), receive.getHospitalName(), xmlHl7Url, filePath, postHl7Url, "1");
//                }
            }
        }
        return new SuccessTip();
    }

    @Override
    public Tip orderWork(OrderInfo receive, HttpServletRequest request, RemoteBillService remoteBillService) throws ExceptionHelp {
        return null;
    }

    @Override
    public Tip outpRegistWork(OrderInfo receive, HttpServletRequest request) throws ExceptionHelp {
        return null;
    }

    @Override
    public Tip outpVisitWork(OrderInfo receive, HttpServletRequest request) throws ExceptionHelp {
        return null;
    }

    @Override
    public Tip newOrderWork(OrderInfo receive, ClinicMaster clinicMaster, OutpMedrec outpMedrec, ApplyInfo applyInfo, HttpServletRequest request, RemoteBillService remoteBillService) throws ExceptionHelp {
        return null;
    }

    @Override
    public Tip orderCancel(CancelOrder CancelOrder, HttpServletRequest request) throws ExceptionHelp {
        return null;
    }

    @Override
    public Tip sendApplyHl7File(OrderInfo orderInfo, String oneKey, String msgType) throws ExceptionHelp {
        return null;
    }

    /**
     * 根据门诊申请订单号获得唯一检验检查单号并推送申请消息
     *
     * @param oneKey
     * @return
     */
    @Override
    public Tip sendBillHl7Msg(String hosCode, String hosName, String oneKey, String type, String hl7Status) throws ExceptionHelp {
        //直接存为xml文件 中间多节点 labHl7Orders
        Map<String, String> hl7InterConfig = getHl7InterConfig(type);
        //XML_HL7_FILE  XML_HL7_URL  WX_HL7_POST_URL
        String filePath = hl7InterConfig.get("filePath");
        String postHl7Url = hl7InterConfig.get("postHl7Url");
        String xmlHl7Url = hl7InterConfig.get("xmlHl7Url");
        if (!oneKey.contains("-")) {
            filePath += oneKey + ".xml";
        } else {
            filePath = oneKey;
        }
        //推送申请
        try {
            pushMessage.sendLabApplyInfo(hosCode, hosName, xmlHl7Url, filePath, postHl7Url, hl7Status);
        } catch (ExceptionHelp e) {
            throw e;
        }
        return new SuccessTip();
    }

    @Override
    public Tip billInpWork(Receive requestVal, HttpServletRequest request) {
        return null;
    }

    /**
     * 门诊计费单个订单业务数据处理 一个billno一次调用 也是收费信息模板计费
     *
     * @param receive
     * @param billNo
     * @return
     */
    public List<ClinicType> commBill(Receive receive, String billNo) throws ExceptionHelp {
        List<ClinicType> clinicTypeList = new ArrayList<>();
        //获取此单号的所有收费项目
        List<Object> itemList = getList(new QueryWrapper<OutpDoctorAssistant>(), billNo, OutpDoctorAssistant.class);
        if (itemList.isEmpty()) {
            itemList = getList(new QueryWrapper<OutpDoctorPrescItems>(), billNo, OutpDoctorPrescItems.class);
        }
        if (itemList.isEmpty()) {
            throw new ExceptionHelp(ExceptionHelpEnum.ALL_ONE_BILL);
        }

        List<Object> outpOrderDescTempList = getList(new QueryWrapper<OutpOrderDescTemp>(), billNo, OutpOrderDescTemp.class);
        if (itemList.isEmpty() || outpOrderDescTempList.size() > 1) {
            throw new ExceptionHelp(ExceptionHelpEnum.ALL_ONE_BILL_ORDER);
        }
        ClinicType clinicType = new ClinicType();
        String type = null;
        List<ClinicItem> clinicItemList = new ArrayList<>();
        OutpOrderDescTemp outpOrderDescTemp = (OutpOrderDescTemp) outpOrderDescTempList.get(0);

        //更新处置表数据失败
        if (outpOrderDescTemp.getPrescIndicator() != 1 && outpDoctorAssistantMapper.updateFlag(billNo.substring(0, 14), billNo.substring(14), "1") < 0) {
            throw new ExceptionHelp(ExceptionHelpEnum.UPDATE_OUTP_Assis);
        }
        if (outpOrderDescTemp.getPrescIndicator() == 1) {
            //更新医嘱处方表中计费标记
            if (!drugPrescMasterMapper.updateChargeFlag(billNo.substring(0, 14), billNo.substring(14))) {
                throw new ExceptionHelp(ExceptionHelpEnum.UPDATE_OUTP_PRESC);
            }
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
            //更新药品处方表中处方标记
            if (drugPrescMasterMapper.updatePrescStatus(billNo.substring(0, 14), billNo.substring(14), AllFinalValueUtils.ALL_OPERATOR, simpleDateFormat.format(new Date()), "计费") <= 0) {
                throw new ExceptionHelp(ExceptionHelpEnum.UPDATE_OUTP_DRUG_PRESC);
            }
        } else {
            if (outpOrderDescTemp.getOrderType() != null && !outpOrderDescTemp.getOrderType().equals("")
                    && (outpOrderDescTemp.getOrderType().equals(AllFinalValueUtils.TEST) || outpOrderDescTemp.getOrderType().equals(AllFinalValueUtils.EXAM))) {
                if (outpOrderDescTemp.getOrderType().equals(AllFinalValueUtils.TEST)) {
                    updateLab(billNo);
                } else {
                    updateExam(billNo);
                }
            }
        }
        for (Object receiveDate : itemList) {
            String itemClass;
            String itemCode;
            String performedBy;
            BigDecimal amount;
            String itemSpec;
            Date visitDate;
            Integer visitNo;
            if (outpOrderDescTemp.getPrescIndicator() == 1) {
                OutpDoctorPrescItems outpDoctorPrescItems = (OutpDoctorPrescItems) receiveDate;
                itemClass = outpDoctorPrescItems.getItemClass();
                itemCode = outpDoctorPrescItems.getPhamCode();
                performedBy = outpDoctorPrescItems.getPerformedBy();
                itemSpec = outpDoctorPrescItems.getPhamSpec() + outpDoctorPrescItems.getFirmId();
                amount = outpDoctorPrescItems.getAmount();
                visitDate = outpDoctorPrescItems.getVisitDate();
                visitNo = outpDoctorPrescItems.getVisitNo();
            } else {
                OutpDoctorAssistant outpDoctorAssistant = (OutpDoctorAssistant) receiveDate;
                itemClass = outpDoctorAssistant.getItemClass();
                itemCode = outpDoctorAssistant.getItemCode();
                performedBy = outpDoctorAssistant.getPerformedBy();
                itemSpec = outpDoctorAssistant.getItemSpec();
                amount = outpDoctorAssistant.getAmount();
                visitDate = outpDoctorAssistant.getVisitDate();
                visitNo = outpDoctorAssistant.getVisitNo();
            }
            if (type != null && !type.equals(itemClass)) {
                clinicType.setType(type == null ? itemClass : type);
                clinicType.setClinicItemList(clinicItemList);
                clinicTypeList.add(clinicType);
                clinicType = new ClinicType();
                clinicItemList = new ArrayList<>();
            }
            clinicType.setType(itemClass);
            List<ClinicVsCharge> clinicVsChargeList = clinicVsChargeMapper.getOrderItemBillDetail(itemClass, itemCode);
            if (itemClass.equals(AllFinalValueUtils.TEATE) || itemClass.equals(AllFinalValueUtils.WEST_DRUG) || itemClass.equals(AllFinalValueUtils.WEST_DRUG)) {
                ClinicVsCharge clinicVsCharge = new ClinicVsCharge();
                clinicVsCharge.setAmount(new BigDecimal(1));
                clinicVsCharge.setChargeItemClass(itemClass);
                clinicVsCharge.setChargeItemCode(itemCode);
                clinicVsCharge.setChargeItemNo(1);
                clinicVsCharge.setChargeItemSpec(itemSpec);
                clinicVsCharge.setClinicItemClass(itemClass);
                clinicVsCharge.setClinicItemCode(itemCode);
                clinicVsChargeList.add(clinicVsCharge);
            }
            if (clinicVsChargeList != null && clinicVsChargeList.size() > 0) {
                ClinicItem clinicItem = new ClinicItem();
                clinicItem.setClinicItemCode(itemCode);
                clinicItem.setPerformedBy(performedBy);
                clinicItem.setItemSpec(itemSpec);
                clinicItem.setPrimaryDate(DateUtil.format(visitDate, "yyyy-MM-dd HH:mm:ss"));
                clinicItem.setPrimaryNo(String.valueOf(visitNo));
                clinicItem.setOrderedBy(outpOrderDescTemp.getOrderedByDept());
                clinicItem.setOperatorNo(AllFinalValueUtils.ALL_OPERATOR);
                //删除单个收费项目收费临时表中数据门诊删除
                List<String> deleteBillItemList = new ArrayList<>();
                for (ClinicVsCharge clinicVsCharge : clinicVsChargeList) {
                    deleteBillItemList.add(clinicVsCharge.getChargeItemCode());
                }
                int deleteBillItems = outpBillItemsTempMapper.deleteBillItems(billNo.substring(0, 14), billNo.substring(14), deleteBillItemList);
                if (deleteBillItems < 0) {
                    throw new ExceptionHelp(ExceptionHelpEnum.FILED_DELETE_BILL);
                }
                clinicItem.setAmount(amount);
                clinicItemList.add(clinicItem);
                type = itemClass;
            } else {
                throw new ExceptionHelp(ExceptionHelpEnum.PRESC_BILL_ITEM);
            }
        }
        clinicType.setClinicItemList(clinicItemList);
        clinicTypeList.add(clinicType);

        //医嘱正式表中是否有数据,以及明细收费临时表中数据是否已经删除完
        int dataOrder = outpOrderDescMapper.getDataOrder(billNo.substring(0, 14), billNo.substring(14));
        List<OutpBillItemsTemp> outpBillItemsTemp = outpBillItemsTempMapper.getOutpBillItemsTemp(billNo.substring(0, 14), billNo.substring(14));

        //无主表数据则插入医嘱主表门诊
        if (dataOrder == 0 && receive.getOutpOrInp().equals(AllFinalValueUtils.OUTP_FLAG)) {
            //获取医嘱临时表中数据并赋值给医嘱正式表
            OutpOrderDesc outpOrderDesc = new OutpOrderDesc();
            BeanUtils.copyProperties(outpOrderDescTemp, outpOrderDesc);
            outpOrderDesc.setRcptNo(receive.getSettlePatientInfo().get(0).getRcptNo());
            outpOrderDesc.setOperatorNo(AllFinalValueUtils.ALL_OPERATOR);
            Integer insert = outpOrderDescMapper.insert(outpOrderDesc);
            if (insert < 0) {
                throw new ExceptionHelp(ExceptionHelpEnum.INSERT_ORDER_DESC);
            }
        }
        if ((outpBillItemsTemp == null || outpBillItemsTemp.isEmpty()) && receive.getOutpOrInp().equals(AllFinalValueUtils.OUTP_FLAG)) {
            //费用临时表中数据若已删除完成则删除临时医嘱主表数据
            int deletTemp = outpOrderDescTempMapper.deletTemp(billNo.substring(0, 14), billNo.substring(14));
            if (deletTemp < 0) {
                throw new ExceptionHelp(ExceptionHelpEnum.DELETE_ORDER_DESC_TEMP);
            }
        }
        return clinicTypeList;
    }


    public boolean updateLab(String billNo) throws ExceptionHelp {
        String testNo = labTestMasterMapper.getTestNo(billNo.substring(0, 14), billNo.substring(14));
        if (testNo != null) {
            QueryWrapper<LabTestItems> labTestItemsEntityWrapper = new QueryWrapper<>();
            labTestItemsEntityWrapper.eq(AllFinalValueUtils.TEST_NO, testNo);
            List<LabTestItems> labTestItemsList = labTestItemsMapper.selectList(labTestItemsEntityWrapper);
            if (labTestItemsList != null && !labTestItemsList.isEmpty() && labTestItemsList != null && !labTestItemsList.isEmpty()) {
                for (LabTestItems labTestItems : labTestItemsList) {
                    //更新单个检验项目收费标记
                    int updateChargeFlag1 = labTestItemsMapper.updateChargeFlag(testNo, labTestItems.getItemCode());
                    if (updateChargeFlag1 < 0) {
                        throw new ExceptionHelp(ExceptionHelpEnum.UPDATE_ITEM_BILL_CHARGE_FLAG);
                    }
                }
                //所有项目收费标记都完成了再更新主表收费标记
                int testNoAllItemChargeFlag = labTestItemsMapper.getTestNoAllItemChargeFlag(testNo);
                if (testNoAllItemChargeFlag == 0) {
                    int updateChargeFlag = labTestMasterMapper.updateChargeFlag(testNo);
                    if (updateChargeFlag < 0) {
                        throw new ExceptionHelp(ExceptionHelpEnum.UPDATE_ITEM_BILL_CHARGE_FLAG);
                    }
                }
            } else {
                throw new ExceptionHelp(ExceptionHelpEnum.REQ_INFOR_ERRE);
            }
        } else {
            throw new ExceptionHelp(ExceptionHelpEnum.REQ_INFOR_NULL);
        }
        return true;
    }

    public boolean updateExam(String billNo) throws ExceptionHelp {
        String examNo = outpDoctorAssistantMapper.getApplyNo(billNo.substring(0, 14), billNo.substring(14), "1");
        if (examNo != null && examNo != "") {
            List<ExamItems> examItemsList = examItemsMapper.selectList(new QueryWrapper<ExamItems>().eq(AllFinalValueUtils.EXAM_NO, examNo));
            if (examItemsList != null && !examItemsList.isEmpty()) {
                ExamAppoints examAppoints = examAppointsMapper.selectById(examNo);
                //所有项目收费标记都完成了再删除预约表数据插入检查主表数据
                ExamMaster examMaster = new ExamMaster();
                BeanUtils.copyProperties(examAppoints, examMaster);
                examMaster.setChargeIndicator(1);
                if (examMasterMapper.insert(examMaster) > 0) {
                    if (examAppointsMapper.delete(new QueryWrapper<ExamAppoints>().eq(AllFinalValueUtils.EXAM_NO, examNo)) <= 0) {
                        throw new ExceptionHelp(ExceptionHelpEnum.DELETE_REQ_INFO);
                    }
                } else {
                    throw new ExceptionHelp(ExceptionHelpEnum.FILED_INSERT_EXAM_MASTER);
                }
                return true;
            }
        } else {
            throw new ExceptionHelp(ExceptionHelpEnum.EXAM_BILL_ITEM);
        }
        return false;
    }

    /**
     * 计费接口基础数据等
     *
     * @param receive
     * @return
     * @throws ExceptionHelp
     */
    private ExceptionHelp checkAllbill(Receive receive) throws ExceptionHelp {
        ExceptionHelp exceptionHelp = null;
//        //接口基础的数据（计费、开单均有的参数）的检查例如医院编码等全接口通用的
//        exceptionHelp = CheckValue(receive);
//        if (exceptionHelp != null) {
//            return exceptionHelp;
//        }
        //仅计费接口的公共计费参数,结算检查针对门诊
        if (receive.getSettleFlag().equals("1") && receive.getOutpOrInp().equals(AllFinalValueUtils.OUTP_FLAG)) {
            if (receive.getSettlePatientInfo() == null || receive.getSettlePatientInfo().size() == 0) {
                return new ExceptionHelp(ExceptionHelpEnum.CHECK_BILL_SETTLE_FLAG);
            }
        }
        //住院判断是否在院
        if (receive.getOutpOrInp().equals(AllFinalValueUtils.INP_FLAG)) {
            int patientInHospital = inpBillDetailMapper.getPatientInHospital(receive.getApplyNo());
            if (patientInHospital <= 0) {
                return new ExceptionHelp(ExceptionHelpEnum.CHECK_BILL_IS_INHOS);
            }
        }
        //检查检验、处方、处置等特殊的计费判断
        exceptionHelp = checkAllBillOther(receive);
        if (exceptionHelp != null) {
            throw exceptionHelp;
        }
        return exceptionHelp;
    }

    /**
     * 分开检查检验、处方、处置等特殊的计费判断
     *
     * @param receive
     * @return
     */
    protected ExceptionHelp checkAllBillOther(Receive receive) throws ExceptionHelp {
        return null;
    }

    /**
     * 检查单个人的结算数据
     *
     * @param wxPayEntity
     * @param billNoList
     * @return
     * @throws ExceptionHelp
     */
    public boolean checkSingleSettleData(WxPayEntity wxPayEntity, String[] billNoList) throws ExceptionHelp {
        if (billNoList == null && billNoList.length == 0) {
            throw new ExceptionHelp(ExceptionHelpEnum.BILL_GET_ORDER_DETAIL);
        }
        if ((wxPayEntity.getClinicTypeList() != null && wxPayEntity.getClinicTypeList().isEmpty() && wxPayEntity.getClinicTypeList().size() > 0)) {
            throw new ExceptionHelp(ExceptionHelpEnum.BILL_GET_ORDER_DETAIL);
        }
        //判断HIS业务单号是否存在未计费数据以及已计费数据
        for (String billNo : billNoList) {
            List<Object> list = getList(new QueryWrapper<OutpOrderDesc>(), billNo, OutpOrderDesc.class);
            if (list != null && list.size() > 0) {
                throw new ExceptionHelp(ExceptionHelpEnum.BILL_OLD);
            }
            List<Object> objectList = getList(new QueryWrapper<OutpOrderDescTemp>(), billNo, OutpOrderDescTemp.class);
            if (objectList == null || objectList.isEmpty() || objectList.size() == 0) {
                throw new ExceptionHelp(ExceptionHelpEnum.BILL_CHECK_OLD);
            }
        }
        return true;
    }

//    /**
//     * HIS排队信息
//     */
//    protected abstract ExceptionHelp setConsult() throws ExceptionHelp;

    /**
     * 获取订单交易的HIS记录
     *
     * @param wxPayEntity
     * @return
     * @throws ExceptionHelp
     */
    private Map<String, Object> getBillNo(String settleFlag, WxPayEntity wxPayEntity) throws ExceptionHelp {
        HashMap<String, Object> map = new HashMap<>();
        OutpPrepayRcptTemp outpPrepayRcptTemp = new OutpPrepayRcptTemp();
        QueryWrapper<OutpPrepayRcptTemp> outpPrepayRcptTempQueryWrapper = new QueryWrapper<>();
        String billNo = wxPayEntity.getBillNo();
        if (billNo == null || billNo.trim().equals("")) {
            throw new ExceptionHelp(ExceptionHelpEnum.BILL_NO_GET_ERROR);
        }
        outpPrepayRcptTempQueryWrapper.eq(AllFinalValueUtils.SETTLE_FLAG_FIELD_NAME, AllFinalValueUtils.SETTLE_FLAG_FIELD_VALUE_FALSE).
                eq(AllFinalValueUtils.PATIENT_ID_FIELD_NAME, wxPayEntity.getPatientId()).eq(AllFinalValueUtils.ORDER_NO_FIELD_NAME, billNo);
        List<OutpPrepayRcptTemp> outpPrepayRcptTempList = outpPrepayRcptTempMapper.selectList(outpPrepayRcptTempQueryWrapper);
        List<OrderVsBillno> orderVsBillnoList = orderVsBillnoList(billNo);
        if (outpPrepayRcptTempList == null || outpPrepayRcptTempList.isEmpty() || outpPrepayRcptTempList.size() > 1) {
            throw new ExceptionHelp(ExceptionHelpEnum.BILL_NO_GET_ERROR);
        }
        if (settleFlag.equals(AllFinalValueUtils.SETTLE_FLAG_FIELD_VALUE_TRUE) && wxPayEntity.getRcptNo() == null) {
            outpPrepayRcptTemp = setOutpPrepayRcptTempValue(outpPrepayRcptTempList.get(0));
        }
        map.put(AllFinalValueUtils.OUTP_PRE_RCPT_TEMP, outpPrepayRcptTemp);
        map.put(AllFinalValueUtils.ORDER_VS_BILL_LIST, orderVsBillnoList);
        return map;
    }

    /**
     * 获取门诊订单记录数据
     *
     * @param outpPrepayRcptTemp
     * @return
     */
    public OutpPrepayRcptTemp setOutpPrepayRcptTempValue(OutpPrepayRcptTemp outpPrepayRcptTemp) {
        AppConfigerBaseinfo appConfigerBaseinfo = getAppConfigerBaseinfo("*", "AUTO_SETTLE_WIN");
        String parainitValue = appConfigerBaseinfo.getParainitValue().trim();
        String parameterScope = appConfigerBaseinfo.getParameterScope().trim();
        String paraScope = String.valueOf(Integer.parseInt(parameterScope) + 1);
        appConfigerBaseinfo.setParameterScope(paraScope);
        try {
            Integer update = appConfigerBaseinfoMapper.update(appConfigerBaseinfo, new QueryWrapper<AppConfigerBaseinfo>().apply(" app_name = '*' and parameter_name = 'AUTO_SETTLE_WIN'"));
        } catch (Exception e) {
            throw new ExceptionHelp(ExceptionHelpEnum.UPDATE_AUTO_SETTLE_NO_FILAD);
        }
        String rcptno = parainitValue + String.format("%06d", Integer.parseInt(parameterScope));
        outpPrepayRcptTemp.setRcptNo(rcptno);
        return outpPrepayRcptTemp;

    }

    /**
     * 根据条件以及类对象名称获取数据集合
     *
     * @param queryWrapper
     * @param billNo
     * @param objectClass
     * @return
     */
    private List<Object> getList(QueryWrapper queryWrapper, String billNo, Class objectClass) throws ExceptionHelp {
        String simpleName = objectClass.getSimpleName();
        queryWrapper.eq(AllFinalValueUtils.OUTP_VISIT_NO, billNo.substring(14));
        queryWrapper.apply("  visit_date = to_date({0},'yyyy-mm-dd hh24:mi:ss')", billNo.substring(0, 14));
        List<Object> objectList;
        if (simpleName.equals(AllFinalValueUtils.OUTP_DOC_ASS)) {
            objectList = outpDoctorAssistantMapper.selectList(queryWrapper);
        } else if (simpleName.equals(AllFinalValueUtils.OUTP_BILL_ITEMS_TEMP)) {
            objectList = outpBillItemsTempMapper.selectList(queryWrapper);
        } else if (simpleName.equals(AllFinalValueUtils.OUTP_DOC_PRESC_ITEMS)) {
            objectList = outpDoctorPrescItemsMapper.selectList(queryWrapper);
        } else if (simpleName.equals(AllFinalValueUtils.OUTP_ORDER_DESC)) {
            objectList = outpOrderDescMapper.selectList(queryWrapper);
        } else if (simpleName.equals(AllFinalValueUtils.LAB_TEST_MASTER)) {
            objectList = labTestMasterMapper.selectList(queryWrapper);
        } else {
            objectList = outpOrderDescTempMapper.selectList(queryWrapper);
        }
        return objectList;
    }


}
